home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume6 / rpc2 / part11 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  31.6 KB

  1. Subject:  v06i099:  Sun RPC Source (rpc2), Part11/11
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: cca!SUN.COM!marks (Mark Stein)
  6. Mod.sources: Volume 6, Issue 99
  7. Archive-name: rpc2/Part11
  8.  
  9. [  I have only verified that this unpacks correctly.  --r$  ]
  10.  
  11. Sun RPC source (part 11 of 11).  This software package contains code
  12. and documentation for Revision 3.0 of the Sun Remote Procedure Call
  13. library.  In addition, a beta version of the XDR/RPC protocol compiler
  14. is included.  Comments about this latest release may be mailed to
  15. sun!rpc or rpc@sun.com.
  16.  
  17. Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  18. unrestricted use provided that this legend is included on all tape
  19. media and as a part of the software program in whole or part.  Users
  20. may copy or modify Sun RPC without charge, but are not authorized to
  21. license or distribute it to anyone else except as part of a product or
  22. program developed by the user.
  23.  
  24. - - - - - - - - - C U T - H E R E - - - - - - - - - - - - - - - - - -
  25. #! /bin/sh
  26. # This is a shell archive, meaning:
  27. # 1. Remove everything above the #! /bin/sh line.
  28. # 2. Save the resulting text in a file.
  29. # 3. Execute the file with /bin/sh (not csh) to create:
  30. #    rpc/rpcgen/rpc_util.c
  31. #    rpc/rpcgen/rpc_util.h
  32. #    rpc/rpcgen/rpcgen.1
  33. #    rpc/rpcgen/xdr_update.c
  34. #    rpc/rpcgen/test/Makefile
  35. #    rpc/rpcgen/test/demo_clnt.c
  36. #    rpc/rpcgen/test/demo_proc.c
  37. #    rpc/rpcgen/test/demo_xdr.x
  38. # This archive created: Mon Jul 14 16:55:53 1986
  39. export PATH; PATH=/bin:/usr/bin:$PATH
  40. for d in rpc rpc/doc rpc/rpclib rpc/tools rpc/toys rpc/rpclib/profiled rpc/rpcgen rpc/rpcgen/test
  41. do
  42.     if test ! -d $d
  43.     then
  44.         echo "shar: Making directory $d"
  45.         mkdir $d
  46.         chmod 755 $d
  47.     fi
  48. done
  49. echo shar: "extracting 'rpc/rpcgen/rpc_util.c'" '(4145 characters)'
  50. if test -f 'rpc/rpcgen/rpc_util.c'
  51. then
  52.     echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_util.c'"
  53. else
  54. sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_util.c'
  55. X#ifndef lint 
  56. Xstatic char sccsid[] = "@(#)rpc_util.c 1.1 86/03/26 (C) 1986 SMI";
  57. X#endif
  58. X/*
  59. X * rpc_util.c, Utility routines for the RPC protocol compiler
  60. X * Copyright (C) 1986, Sun Microsystems, Inc.
  61. X */
  62. X#include <stdio.h>
  63. X#include "rpc_scan.h"
  64. X#include "rpc_util.h"
  65. X
  66. Xchar curline[MAXLINESIZE];        /* current read line */
  67. Xchar *where = curline;            /* current point in line */
  68. Xint linenum = 0;                /* current line number */
  69. X
  70. Xchar *infile;    /* input filename */
  71. Xchar *outfile;  /* output filename */
  72. Xchar *outfile2; /* possible other output filename */
  73. X
  74. XFILE *fout;        /* file pointer of current output */
  75. XFILE *fin;        /* file pointer of current input */
  76. X
  77. Xlist *printed;    /* list of printed routines */
  78. Xlist *defined;  /* list of defined things */
  79. X
  80. X/*
  81. X * Reinitialize the world
  82. X */
  83. Xreinitialize()
  84. X{
  85. X    bzero(curline,MAXLINESIZE);
  86. X    where = curline;
  87. X    linenum = 0;
  88. X    printed = NULL;
  89. X    defined = NULL;
  90. X}
  91. X
  92. X/*
  93. X * string equality
  94. X */
  95. Xstreq(a,b)
  96. X    char *a;
  97. X    char *b;
  98. X{
  99. X    return(strcmp(a,b) == 0);
  100. X}
  101. X
  102. X/*
  103. X * find a value in a list
  104. X */
  105. Xchar *
  106. Xfindval(lst,val,cmp)
  107. X    list *lst;
  108. X    char *val;
  109. X    int (*cmp)();
  110. X{
  111. X    for (; lst != NULL; lst = lst->next) {
  112. X        if ((*cmp)(lst->val,val)) {
  113. X            return(lst->val);
  114. X        }
  115. X    }    
  116. X    return(NULL);
  117. X}
  118. X
  119. X/*
  120. X * store a value in a list
  121. X */
  122. Xvoid
  123. Xstoreval(lstp,val)
  124. X    list **lstp;
  125. X    char *val;
  126. X{
  127. X    list **l;
  128. X    list *lst;
  129. X
  130. X    for (l = lstp; *l != NULL; l = (list **) &(*l)->next) 
  131. X        ;
  132. X    lst = ALLOC(list);
  133. X    lst->val = val;
  134. X    lst->next = NULL;
  135. X    *l = lst;
  136. X}
  137. X
  138. X
  139. X/*
  140. X * print a useful (?) error message, and then die
  141. X */
  142. Xvoid
  143. Xerror(msg)
  144. X    char *msg;
  145. X{
  146. X    extern char *outfile;
  147. X
  148. X    printwhere();
  149. X    fprintf(stderr,"%s, line %d: ",infile ? infile : "<stdin>", linenum);
  150. X    fprintf(stderr,"%s\n",msg);
  151. X    crash();
  152. X}
  153. X
  154. X/*
  155. X * Something went wrong, unlink any files
  156. X * that we may have created and then die.
  157. X */
  158. Xcrash()
  159. X{
  160. X    if (outfile) {
  161. X        unlink(outfile);
  162. X    }    
  163. X    if (outfile2) {
  164. X        unlink(outfile2);
  165. X    }
  166. X    exit(1);
  167. X}
  168. X
  169. X
  170. X
  171. Xstatic char expectbuf[100];
  172. Xstatic char *toktostr();
  173. X
  174. X/*
  175. X * error, token encountered was not the expected one
  176. X */
  177. Xvoid
  178. Xexpected1(exp1)
  179. X    tok_kind exp1;
  180. X{
  181. X    sprintf(expectbuf,"expected '%s'",
  182. X        toktostr(exp1));
  183. X    error(expectbuf);
  184. X}
  185. X
  186. X/*
  187. X * error, token encountered was not one of two expected ones
  188. X */
  189. Xvoid
  190. Xexpected2(exp1,exp2)
  191. X    tok_kind exp1,exp2;
  192. X{
  193. X    sprintf(expectbuf,"expected '%s' or '%s'",
  194. X        toktostr(exp1),
  195. X        toktostr(exp2));
  196. X    error(expectbuf);
  197. X}
  198. X
  199. X/*
  200. X * error, token encountered was not one of 3 expected ones
  201. X */
  202. Xvoid
  203. Xexpected3(exp1,exp2,exp3)
  204. X    tok_kind exp1,exp2,exp3;
  205. X{
  206. X    sprintf(expectbuf,"expected '%s', '%s' or '%s'",
  207. X        toktostr(exp1),
  208. X        toktostr(exp2),
  209. X        toktostr(exp3));
  210. X    error(expectbuf);
  211. X}
  212. X
  213. X
  214. X
  215. Xstatic token tokstrings[] = {
  216. X    { TOK_IDENT, "identifier" },
  217. X    { TOK_CONST, "constant" },
  218. X    { TOK_RPAREN, ")" },
  219. X    { TOK_LPAREN, "(" },
  220. X    { TOK_RBRACE, "}" },
  221. X    { TOK_LBRACE, "{" },
  222. X    { TOK_LBRACKET, "[" },
  223. X    { TOK_RBRACKET, "]" },
  224. X    { TOK_STAR, "*" },
  225. X    { TOK_COMMA, "," },
  226. X    { TOK_EQUAL, "=" },
  227. X    { TOK_COLON, ":" },
  228. X    { TOK_SEMICOLON, ";" },
  229. X    { TOK_UNION, "union" },
  230. X    { TOK_STRUCT, "struct" },
  231. X    { TOK_SWITCH, "switch" },
  232. X    { TOK_CASE,    "case" },
  233. X    { TOK_DEFAULT, "default" },
  234. X    { TOK_ENUM, "enum" },
  235. X    { TOK_ARRAY, "array" },
  236. X    { TOK_TYPEDEF, "typedef" },
  237. X    { TOK_INT, "int" },
  238. X    { TOK_SHORT, "short" },
  239. X    { TOK_LONG, "long" },
  240. X    { TOK_UNSIGNED, "unsigned" },
  241. X    { TOK_DOUBLE, "double" },
  242. X    { TOK_FLOAT, "float" },
  243. X    { TOK_CHAR, "char" },
  244. X    { TOK_STRING, "string" },
  245. X    { TOK_OPAQUE, "opaque" },
  246. X    { TOK_BOOL, "bool" },
  247. X    { TOK_VOID, "void" },
  248. X    { TOK_PROGRAM, "program" },
  249. X    { TOK_VERSION, "version" },
  250. X    { TOK_EOF, "??????" }
  251. X};
  252. Xstatic char * 
  253. Xtoktostr(kind) 
  254. X    tok_kind kind; 
  255. X{ 
  256. X    token *sp;
  257. X
  258. X    for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++)
  259. X        ; 
  260. X    return(sp->str); 
  261. X}
  262. X
  263. X
  264. Xstatic 
  265. Xprintbuf()
  266. X{
  267. X    char c;
  268. X    int i;
  269. X    int cnt;
  270. X
  271. X#    define TABSIZE 4
  272. X
  273. X    for (i = 0; c = curline[i]; i++) {
  274. X        if (c == '\t') {
  275. X            cnt = 8 - (i % TABSIZE);
  276. X            c = ' ';
  277. X        } else {
  278. X            cnt = 1;
  279. X        }
  280. X        while (cnt--) {    
  281. X            putc(c,stderr);
  282. X        } 
  283. X    }
  284. X}
  285. X
  286. X
  287. Xstatic
  288. Xprintwhere()
  289. X{
  290. X    int i;
  291. X    char c;
  292. X    int cnt;
  293. X
  294. X    printbuf();
  295. X    for (i = 0; i < where - curline; i++) {
  296. X        c = curline[i];
  297. X        if (c == '\t') {
  298. X            cnt = 8 - (i % TABSIZE);
  299. X        } else {
  300. X            cnt = 1;
  301. X        }
  302. X        while (cnt--) {
  303. X            putc('^',stderr);
  304. X        }
  305. X    }
  306. X    putc('\n',stderr);
  307. X}
  308. SHAR_EOF
  309. if test 4145 -ne "`wc -c < 'rpc/rpcgen/rpc_util.c'`"
  310. then
  311.     echo shar: "error transmitting 'rpc/rpcgen/rpc_util.c'" '(should have been 4145 characters)'
  312. fi
  313. chmod 444 'rpc/rpcgen/rpc_util.c'
  314. fi
  315. echo shar: "extracting 'rpc/rpcgen/rpc_util.h'" '(1202 characters)'
  316. if test -f 'rpc/rpcgen/rpc_util.h'
  317. then
  318.     echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_util.h'"
  319. else
  320. sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_util.h'
  321. X/* @(#)rpc_util.h 1.1 86/03/26 (C) 1986 SMI */
  322. X
  323. X/*
  324. X * rpc_util.h, Useful definitions for the RPC protocol compiler
  325. X * Copyright (C) 1986, Sun Microsystems, Inc.
  326. X */
  327. X
  328. Xextern char *malloc();
  329. Xextern char *sprintf();
  330. X#define alloc(size)        malloc((unsigned)(size))
  331. X#define ALLOC(object)   (object *) malloc(sizeof(object)) 
  332. X
  333. X#define OFF 0
  334. X#define ON 1
  335. X
  336. Xstruct list {
  337. X    char *val;
  338. X    struct list *next;
  339. X};
  340. Xtypedef struct list list;
  341. X
  342. X/*
  343. X * Global variables
  344. X */
  345. X#define MAXLINESIZE 1024
  346. Xextern char curline[MAXLINESIZE];
  347. Xextern char *where;
  348. Xextern int linenum;
  349. X
  350. Xextern char *outfile;
  351. Xextern char *outfile2;
  352. Xextern char *infile;
  353. Xextern FILE *fout;
  354. Xextern FILE *fin;
  355. X
  356. Xextern list *printed;
  357. Xextern list *defined;
  358. X
  359. X
  360. X/*
  361. X * rpc_util routines
  362. X */
  363. Xvoid storeval();
  364. X#define STOREVAL(list,item)    \
  365. X    storeval(list,(char *)item)
  366. X
  367. Xchar *findval();
  368. X#define FINDVAL(list,item,finder) \
  369. X    findval(list, (char *) item, finder)
  370. X
  371. Xint streq();
  372. Xvoid error();
  373. Xvoid expected1();
  374. Xvoid expected2();
  375. Xvoid expected3();
  376. X
  377. X/*
  378. X * rpc_cout routines
  379. X */
  380. Xvoid cprint();
  381. Xvoid emit();
  382. X
  383. X/*
  384. X * rpc_hout routines
  385. X */
  386. Xvoid print_datadef();
  387. Xvoid print_funcdefs();
  388. X
  389. X/*
  390. X * rpc_svcout routines
  391. X */
  392. Xvoid write_most();
  393. Xvoid write_register();
  394. Xvoid write_rest();
  395. X
  396. SHAR_EOF
  397. if test 1202 -ne "`wc -c < 'rpc/rpcgen/rpc_util.h'`"
  398. then
  399.     echo shar: "error transmitting 'rpc/rpcgen/rpc_util.h'" '(should have been 1202 characters)'
  400. fi
  401. chmod 444 'rpc/rpcgen/rpc_util.h'
  402. fi
  403. echo shar: "extracting 'rpc/rpcgen/rpcgen.1'" '(11239 characters)'
  404. if test -f 'rpc/rpcgen/rpcgen.1'
  405. then
  406.     echo shar: "will not over-write existing file 'rpc/rpcgen/rpcgen.1'"
  407. else
  408. sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpcgen.1'
  409. X.\" @(#)rpcgen.1 1.1 86/04/15 SMI
  410. X.TH RPCGEN 1 "11 March 1986"
  411. X.SH NAME
  412. Xrpcgen \- an RPC protocol compiler
  413. X.SH SYNOPSIS
  414. X\fBrpcgen\fP \fB-h\fP \fB[-o \fIoutfile\fP]\fP \fB[\fIinputfile\fP]\fP
  415. X.br
  416. X\fBrpcgen\fP \fB-c\fP \fB[-o \fIoutfile\fP]\fP \fB[\fIinfile\fP]\fP 
  417. X.br
  418. X\fBrpcgen\fP \fIinfile\fP
  419. X.br
  420. X\fBrpcgen\fP \fB[-s \fItransport\fP]*\fP \fB[-o\fP \fIoutfile\fP]\fP \fB[\fIinfile\fP]\fP 
  421. X.br
  422. X.SH DESCRIPTION
  423. X\fIrpcgen\fP is a tool that generates 
  424. X.B C 
  425. Xcode to implement an 
  426. X.SM RPC
  427. Xprotocol.  The input to \fIrpcgen\fP is a language with striking 
  428. Xsimilarity to 
  429. X.B C 
  430. Xknown as RPCL (Remote Procedure Call Language).
  431. X.I rpcgen 
  432. Xoperates in four modes.  The first mode is used to convert
  433. XRPCL definitions into 
  434. X.B C 
  435. Xdefinitions for use as a header file.
  436. XThe second mode compiles the XDR routines required to serialize the protocol
  437. Xdescribed by RPCL.  The third mode compiles both, leaving the
  438. Xheader file in a file named \fIinfile\fP with a 
  439. X.B .h 
  440. Xextension and the XDR routines in \fIinfile\fP with a 
  441. X.B .c 
  442. Xextension.  The fourth mode is used to compile an RPC server skeleton, so that 
  443. Xall you have to do is write local procedures that know nothing about RPC
  444. Xin order to implement an RPC server.
  445. X.LP
  446. XThe input may contain 
  447. X.BR C -style 
  448. Xcomments and preprocessor directives.  Comments are ignored, while the 
  449. Xdirectives are simply stuffed uninterpreted in the output header file. 
  450. X.LP
  451. XYou can customize some of your XDR routines by leaving those data
  452. Xtypes undefined.  For every data type that is undefined, \fIrpcgen\fP 
  453. Xwill assume that there exists a routine with the name `xdr_' prepended
  454. Xto the name of the undefined type. 
  455. X.SH OPTIONS
  456. X.IP \fB-c\fP
  457. XCompile XDR routines.
  458. X.IP \fB-h\fP
  459. XCompile 
  460. X.B C 
  461. Xdata-definitions (a header file)
  462. X.IP "\fB-o\fP \fIoutfile\fP"
  463. XSpecify the name of the output file.  If none is specified, standard
  464. Xoutput is used (\fB-c\fP, \fB-h\fP and \fB-s\fP modes only).
  465. X.IP "\fB-s\fP \fItransport\fP"
  466. XCompile a server, using the the given transport.  The supported transports
  467. Xare \fBudp\fP and \fBtcp\fP. This option may be invoked more than once
  468. Xso as to compile a server that serves multiple transports.
  469. X.SH USAGE
  470. X.SS "RPCL Syntax Summary"
  471. XThis summary of RPCL syntax, which is used for 
  472. X.I rpcgen 
  473. Xinput, is intended more for aiding 
  474. Xcomprehension than as an exact statement of the language.
  475. X.SS "Primitive Data Types"
  476. X.RS
  477. X.nf
  478. X[ \fBunsigned\fP ] \fBchar\fP
  479. X[ \fBunsigned\fP ] \fBshort\fP
  480. X[ \fBunsigned\fP ] \fBint\fP
  481. X[ \fBunsigned\fP ] \fBlong\fP
  482. X\fBunsigned\fP
  483. X\fBfloat\fP
  484. X\fBdouble\fP
  485. X\fBvoid\fP
  486. X\fBbool\fP
  487. X.fi
  488. X.RE
  489. XExcept for the added boolean data-type \fBbool\fP,
  490. XRPCL is identical to 
  491. X.BR C .
  492. X\fIrpcgen\fP converts \fBbool\fP declarations to \fBint\fP declarations in the 
  493. Xoutput header file (literally it is converted to a \fBbool_t\fP, which has been
  494. X\fB#define\fP'd to be an \fBint\fP). Also, \fBvoid\fP declarations
  495. Xmay appear only inside of 
  496. X.B union 
  497. Xand 
  498. X.B program 
  499. Xdefinitions.  For those averse to typing the prefix 
  500. X\fBunsigned\fP, the abbreviations \fBu_char\fP, \fBu_short\fP, \fBu_int\fP and 
  501. X\fBu_long\fP are available. 
  502. X.SS Declarations
  503. XRPCL allows only three kinds of declarations:
  504. X.LP
  505. X\fIdeclaration:\fP
  506. X.RS
  507. X.nf
  508. X\fIsimple-declaration\fP
  509. X\fIpointer-declaration\fP
  510. X\fIvector-declaration\fP
  511. X.fi
  512. X.RE
  513. X.LP
  514. X\fIsimple-declaration:\fP
  515. X.RS
  516. X\fItype-name\fP \fIobject-ident\fP
  517. X.RE
  518. X.LP    
  519. X\fIpointer-declaration:\fP
  520. X.RS
  521. X\fItype-name\fP \fB*\fP\fIobject-ident\fP
  522. X.RE
  523. X.LP
  524. X\fIvector-declaration:\fP
  525. X.RS
  526. X\fItype-name\fP \fIobject-ident\fP\fB[\fP\fIsize\fP\fB]\fP
  527. X.RE
  528. X.LP 
  529. X(\fIsize\fP can be either an integer or a symbolic constant)
  530. X.RE
  531. X.LP
  532. XRPCL declarations contain both limitations and extensions with
  533. Xrespect to 
  534. X.BR C .  
  535. XThe limitations are that you cannot declare
  536. Xmultidimensional arrays or pointers-to-pointers in-line (You
  537. Xcan still declare them though, using \fBtypedef\fP). There
  538. Xare two extensions:
  539. X.LP
  540. X.RS
  541. XOpaque data is declared as a vector as follows:
  542. X.LP
  543. X.RS
  544. X\fBopaque\fP \fIobject-ident\fP \fB[\fP \fIsize\fP \fB]\fP
  545. X.RE
  546. X.LP
  547. XIn the protocol, this results in an object of \fIsize\fP bytes. Note that
  548. Xthis is \fInot\fP the same as a declaration of \fIsize\fP characters, 
  549. Xsince XDR characters are 32-bits. Opaque declarations are compiled in the
  550. Xoutput header file into character array declarations of \fIsize\fP bytes.
  551. X.LP
  552. XStrings are special and are declared as a vector declaration:
  553. X.LP
  554. X.RS
  555. X\fBstring\fP \fIobject-ident\fP \fB[\fP \fImax-size\fP \fB]\fP
  556. X.RE
  557. X.LP
  558. XIf \fImax-size\fP is unspecified, then there is essentially no limit to
  559. Xthe maximum length of the string. String declarations get compiled into
  560. Xthe following:
  561. X.LP
  562. X.RS
  563. Xchar *\fIobject-ident\fP
  564. X.RE
  565. X.RE
  566. X.RE
  567. X.SS "Type Definitions"
  568. XThe only way to generate an XDR routine is to define a type. For
  569. Xevery type \fIzetype\fP you define, there is a corresponding
  570. XXDR routine named \fIxdr_zetype\fP.  
  571. X.LP
  572. XThere are six ways to define a type:
  573. X.LP
  574. X\fItype-definition:\fP
  575. X.RS
  576. X.nf
  577. X\fItypedef\fP
  578. X\fIenumeration-def\fP
  579. X\fIstructure-def\fP
  580. X\fIvariable-length-array-def\fP
  581. X\fIdiscriminated-union-def\fP
  582. X\fIprogram-def\fP
  583. X.fi
  584. X.RE
  585. X.LP
  586. XThe first three are very similar to their 
  587. X.B C 
  588. Xnamesakes. 
  589. X.B C 
  590. Xdoes not have a formal type mechanism to define variable-length arrays and
  591. XXDR unions are quite different from their 
  592. X.B C 
  593. Xcounterparts. Program definitions are not really type definitions, 
  594. Xbut they are useful nonetheless.
  595. X.LP
  596. XYou may not nest XDR definitions.  For example, the following will 
  597. Xcause \fIrpcgen\fP to choke:
  598. X.RS
  599. X.nf
  600. Xstruct dontdoit {
  601. X    struct ididit {
  602. X        int oops;
  603. X    } sorry;
  604. X    enum ididitagain { OOPS, WHOOPS } iapologize;
  605. X};
  606. X.fi
  607. X.RE
  608. X.SS \fRTypedefs
  609. XAn XDR \fBtypedef\fP looks as follows:
  610. X.LP
  611. X\fItypedef:\fP
  612. X.RS
  613. X\fBtypedef\fP \fIdeclaration\fP \fB;\fP
  614. X.RE
  615. XThe \fIobject-ident\fP part of \fIdeclaration\fP is the name of the new type,
  616. Xwhereas the \fItype-name\fP part is the name of the type from which it is
  617. Xderived.
  618. X.LP
  619. X.SS "\fIEnumeration Types"
  620. XThe syntax is:
  621. X.LP
  622. X\fIenumeration-def:\fP
  623. X.RS
  624. X\fBenum\fP \fIenum-ident\fP \fB{\fP
  625. X.RS
  626. X\fIenum-list\fP
  627. X.RE
  628. X\fB};\fP
  629. X.RE
  630. X.LP
  631. X\fIenum-list:\fP
  632. X.RS
  633. X\fIenum-symbol-ident\fP [ \fB=\fP \fIassignment\fP ]
  634. X.br
  635. X\fIenum-symbol-ident\fP [ \fB=\fP \fIassignment\fP ] \fB,\fP \fIenum-list\fP
  636. X.RE
  637. X.LP
  638. X(\fIassignment\fP may be either an integer or a symbolic constant)
  639. X.LP
  640. XIf there is no explicit assignment, then the implicit assignment is the
  641. Xvalue of the previous enumeration plus 1.  If not explicitly assigned,
  642. Xthe first enumeration receives the value 0.
  643. X.SS \fIStructures
  644. X\fIstructure-def:\fP
  645. X.RS
  646. X\fBstruct\fP \fIstruct-ident\fP \fB{\fP
  647. X.RS
  648. X\fIdeclaration-list\fP
  649. X.RE
  650. X\fB};\fP
  651. X.RE
  652. X.LP
  653. X\fIdeclaration-list:\fP
  654. X.RS
  655. X\fIdeclaration\fP \fB;\fP
  656. X.br
  657. X\fIdeclaration\fP \fB;\fP \fIdeclaration-list\fP
  658. X.RE
  659. X.RE
  660. X.LP
  661. X.SS "\fIVariable-Length Arrays"
  662. X\fIvariable-length-array-def:\fP
  663. X.RS
  664. X\fBarray\fP \fIarray-ident\fP \fB{\fP
  665. X.RS
  666. X\fBunsigned\fP \fIlength-identifer\fP \fB;\fP
  667. X.br
  668. X\fIvector-declaration\fP \fB;\fP
  669. X.RE
  670. X\fB};\fP
  671. X.RE
  672. X.LP    
  673. XA variable length array definition looks much like a structure 
  674. Xdefinition. Here's an example:
  675. X.RS
  676. X.nf
  677. Xarray mp_int {
  678. X    unsigned len;
  679. X    short val[MAX_MP_LENGTH];
  680. X};
  681. X.fi
  682. X.RE
  683. XThis is compiled into:
  684. X.RS
  685. X.nf
  686. Xstruct mp_int {
  687. X    unsigned len;
  688. X    short *val;
  689. X};
  690. Xtypedef struct mp_int mp_int;
  691. X.fi
  692. X.RE
  693. X.SS "\fIDisriminated Unions"
  694. X\fIdiscriminated-union-def:\fP
  695. X.RS
  696. X\fBunion\fP \fIunion-ident\fP \fBswitch\fP \fB(\fP \fIdiscriminant-declaration\fP \fB)\fP \fB{\fP
  697. X.RS
  698. X\fIcase-list\fP
  699. X.br
  700. X[ \fBdefault\fP \fB:\fP \fIdeclaration\fP \fB;\fP ]
  701. X.RE
  702. X\fB};\fP
  703. X.RE
  704. X.LP
  705. X\fIcase-list:\fP
  706. X.RS
  707. X\fBcase\fP \fIcase-ident\fP \fB:\fP \fIdeclaration\fP \fB;\fP
  708. X.br
  709. X\fBcase\fP \fIcase-ident\fP \fB:\fP \fIdeclaration\fP \fB;\fP \fIcase-list\fP
  710. X.RE
  711. X.LP
  712. X\fIdiscriminant-declaration:\fP
  713. X.RS
  714. X\fIdeclaration\fP
  715. X.RE
  716. X.LP
  717. XThe union definition looks like a cross between a C-union and a C-switch.
  718. XAn example:
  719. X.RS
  720. X.nf
  721. Xunion net_object switch (net_kind kind) {
  722. Xcase MACHINE:
  723. X    struct sockaddr_in sin;
  724. Xcase USER:
  725. X    int uid;
  726. Xdefault:
  727. X    string whatisit;
  728. X};
  729. X.fi
  730. X.RE
  731. XCompiles into:
  732. X.RS
  733. X.nf
  734. Xstruct net_object {
  735. X    net_kind kind;
  736. X    union {
  737. X        struct sockaddr_in sin;
  738. X        int uid;
  739. X        char *whatisit;
  740. X    } net_object;
  741. X};
  742. Xtypedef struct net_object net_object;
  743. X.fi
  744. X.RE
  745. XNote that the name of the union component of the output struct is the
  746. Xsame as the name of the type itself.
  747. X.SS "\fIProgram Definitions"
  748. X\fIprogram-def:\fP
  749. X.RS
  750. X\fBprogram\fP \fIprogram-ident\fP \fB{\fP
  751. X.RS
  752. X\fIversion-list\fP
  753. X.RE
  754. X\fB}\fP \fB=\fP \fIprogram-number\fP \fB;\fP
  755. X.RE
  756. X.LP
  757. X\fIversion-list:\fP
  758. X.RS
  759. X\fIversion\fP
  760. X.br
  761. X\fIversion\fP \fIversion-list\fP
  762. X.RE
  763. X\fIversion:\fP
  764. X.RS
  765. X\fBversion\fP \fIversion-ident\fP \fB{\fP
  766. X.RS
  767. X\fIprocedure-list\fP
  768. X.RE
  769. X\fB} =\fP \fIversion-number\fP \fB;\fP
  770. X.RE
  771. X\fIprocedure-list:\fP
  772. X.RS
  773. X\fIprocedure-declaration\fP
  774. X.br
  775. X\fIprocedure-declaration procedure-list\fP
  776. X.RE
  777. X\fIprocedure-declaration:\fP
  778. X.RS
  779. X\fItype-name\fP \fIprocedure-ident\fP \fB(\fP \fItype-name\fP \fB)\fP \fB=\fP \fIprocedure-number\fP \fB;\fP
  780. X.RE
  781. X.LP
  782. XProgram definitions look like nothing you've ever seen before, so we
  783. Xturn to an example to explain them.  Suppose you wanted to create server
  784. Xthat could get or set the date. It's declaration might look like this:
  785. X.RS
  786. X.nf
  787. Xprogram DATE_PROG {
  788. X    version DATE_VERS {
  789. X        date DATE_GET(timezone) = 1;
  790. X        void DATE_SET(date) = 2;    /* Greenwich mean time */
  791. X    } = 1;
  792. X} = 100;
  793. X.fi
  794. X.RE
  795. XIn the header file, this compiles into the following:
  796. X.RS
  797. X.nf
  798. X#define DATE_PROG 100
  799. X#define DATE_VERS 1
  800. X#define DATE_GET 1
  801. X#define DATE_SET 2
  802. X.fi
  803. X.RE
  804. XThese \fBdefine\fP's are intended for use by the client program to 
  805. Xreference the remote procedures. 
  806. X.LP
  807. XIf you are using \fIrpcgen\fP to compile your server, then there are
  808. Xsome important things for you to know. The server interfaces to
  809. Xyour local procedures by expecting a 
  810. X.B C 
  811. Xfunction with the same name as that in the program definition, but in all 
  812. Xlower-case letters and followed by the version number.  Here is the local 
  813. Xprocedure that implements DATE_GET:
  814. X.RS
  815. X.nf
  816. Xdate *    /* always returns a pointer to the results */
  817. Xdate_get_1(tz)    
  818. X    timezone *tz;    /* always takes a a pointer to the arguments */
  819. X{
  820. X    static date d;    /* must be static! */
  821. X    
  822. X    /* 
  823. X     * figure out the date
  824. X     * and store it in d
  825. X     */
  826. X    return(&d);    
  827. X}
  828. X.fi
  829. X.RE
  830. XThe name of the routine is the same as the \fB#define\fP'd name, but in all 
  831. Xlower case letters and followed by the version number. XDR will recursively 
  832. Xfree the argument after getting the 
  833. Xresults from your local procedure, so you should copy from the argument 
  834. Xany data that you will need between calls. However, XDR neither allocates 
  835. Xnor frees your results. You must take care of their storage yourself.
  836. X.LP
  837. X.SS "Make Inference Rules For Compiling XDR Headers"
  838. X.LP
  839. XIt is possible to set up suffix transformation rules in 
  840. X.IR make  (1)
  841. Xfor compiling XDR routines and header files.  The 
  842. Xconvention is that RPCL protocol files have the extension 
  843. X.BR .x .  
  844. XThe \fImake\fP rules to do this are:
  845. X.nf
  846. X    .SUFFIXES: .x
  847. X    .x.c: 
  848. X        rpcgen -c $< -o $@
  849. X
  850. X    .x.h:
  851. X        rpcgen -h $< -o $@
  852. X.fi
  853. X.SH "SEE ALSO"
  854. X\fIRemote Procedure Call: Programming Guide\fP 
  855. Xand \fIExternal Data Representation: Protocol Specification\fP 
  856. Xin\fI Networking on the Sun Workstation\fP
  857. X.SH BUGS
  858. XName clashes can occur when using program definitions, since the apparent
  859. Xscoping does not really apply. Most of these can be avoided by giving 
  860. Xunique names for programs, versions, procedures and types.
  861. SHAR_EOF
  862. if test 11239 -ne "`wc -c < 'rpc/rpcgen/rpcgen.1'`"
  863. then
  864.     echo shar: "error transmitting 'rpc/rpcgen/rpcgen.1'" '(should have been 11239 characters)'
  865. fi
  866. chmod 444 'rpc/rpcgen/rpcgen.1'
  867. fi
  868. echo shar: "extracting 'rpc/rpcgen/xdr_update.c'" '(1993 characters)'
  869. if test -f 'rpc/rpcgen/xdr_update.c'
  870. then
  871.     echo shar: "will not over-write existing file 'rpc/rpcgen/xdr_update.c'"
  872. else
  873. sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/xdr_update.c'
  874. X/*
  875. X * xdr_update.c: Additions to release 3.0 XDR routines required
  876. X *    for rpcgen.  These routines are from release 3.2BETA and
  877. X *    may be updated before final release.
  878. X *
  879. X * Copyright (C) 1986, Sun Microsystems, Inc.
  880. X *
  881. X */
  882. X
  883. X#include <rpc/rpc.h>
  884. X#define NULL 0
  885. X#define LASTUNSIGNED    ((u_int)0-1)
  886. X
  887. X/*
  888. X * xdr_pointer():
  889. X *
  890. X * XDR a pointer to a possibly recursive data structure. This
  891. X * differs with xdr_reference in that it can serialize/deserialiaze
  892. X * trees correctly.
  893. X *
  894. X *  What's sent is actually a union:
  895. X *
  896. X *  union object_pointer switch (boolean b) {
  897. X *  case TRUE: object_data data;
  898. X *  case FALSE: void nothing;
  899. X *  }
  900. X *
  901. X * > objpp: Pointer to the pointer to the object.
  902. X * > obj_size: size of the object.   
  903. X * > xdr_obj: routine to XDR an object.
  904. X *    
  905. X */
  906. Xbool_t                        
  907. Xxdr_pointer(xdrs,objpp,obj_size,xdr_obj)
  908. X        register XDR *xdrs;
  909. X        char **objpp;
  910. X        u_int obj_size;
  911. X        xdrproc_t xdr_obj;
  912. X{                      
  913. X                       
  914. X        bool_t more_data;
  915. X                
  916. X        more_data = (*objpp != NULL);
  917. X        if (! xdr_bool(xdrs,&more_data)) {
  918. X                return(FALSE);
  919. X        }
  920. X        if (! more_data) {
  921. X                *objpp = NULL;
  922. X                return(TRUE);
  923. X        }
  924. X        return(xdr_reference(xdrs,objpp,obj_size,xdr_obj));
  925. X}
  926. X
  927. X/*
  928. X * xdr_vector():
  929. X *
  930. X * XDR a fixed length array. Unlike variable-length arrays,
  931. X * the storage of fixed length arrays is static and unfreeable.
  932. X * > basep: base of the array
  933. X * > size: size of the array
  934. X * > elemsize: size of each element
  935. X * > xdr_elem: routine to XDR each element
  936. X */
  937. Xbool_t
  938. Xxdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
  939. X    register XDR *xdrs;
  940. X    register char *basep;
  941. X    register u_int nelem;
  942. X    register u_int elemsize;
  943. X    register xdrproc_t xdr_elem;    
  944. X{
  945. X    register u_int i;
  946. X    register char *elptr;
  947. X
  948. X    elptr = basep;
  949. X    for (i = 0; i < nelem; i++) {
  950. X        if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
  951. X            return(FALSE);
  952. X        }
  953. X        elptr += elemsize;
  954. X    }
  955. X    return(TRUE);    
  956. X}
  957. SHAR_EOF
  958. if test 1993 -ne "`wc -c < 'rpc/rpcgen/xdr_update.c'`"
  959. then
  960.     echo shar: "error transmitting 'rpc/rpcgen/xdr_update.c'" '(should have been 1993 characters)'
  961. fi
  962. chmod 664 'rpc/rpcgen/xdr_update.c'
  963. fi
  964. echo shar: "extracting 'rpc/rpcgen/test/Makefile'" '(1274 characters)'
  965. if test -f 'rpc/rpcgen/test/Makefile'
  966. then
  967.     echo shar: "will not over-write existing file 'rpc/rpcgen/test/Makefile'"
  968. else
  969. sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/test/Makefile'
  970. X#  Makefile for the demo rpc service for rpcgen
  971. X#
  972. X#  There are three source files used by this makefile:
  973. X#    demo_xdr.x    Demo protocol specification used as input
  974. X#            by rpcgen to generate demo_xdr.h (xdr
  975. X#            defines and data type decarations),
  976. X#            demo_xdr.c (xdr data type routines),
  977. X#            and demo.c (server program shell)
  978. X#    demo_proc.c    The actual procedure handlers for the server.
  979. X#    demo_clnt.c    The client program.
  980. X
  981. X.SUFFIXES: .x .c .h .o
  982. XCC = cc
  983. X
  984. X# REL3_0 should be defined in CFLAGS if using a pre-3.2 rpc library
  985. XCFLAGS = -DREL3_0
  986. X
  987. XRPCGEN = ../rpcgen
  988. XPROTO = udp
  989. X
  990. XSOBJS = demo.o demo_proc.o demo_xdr.o 
  991. XCOBJS = demo_clnt.o demo_xdr.o 
  992. X
  993. X# RPCLIB should be the rpc library, or commented out if included in libc.
  994. X# xdr_update.o should be included if linking with a pre-3.2 rpc library.
  995. X#RPCLIB = -lrpc
  996. XRPCLIB = ../xdr_update.o
  997. X
  998. X.x.c:
  999. X    $(RPCGEN) -c $< -o $@
  1000. X.x.h:
  1001. X    $(RPCGEN) -h $< -o $@
  1002. X
  1003. Xall: demo_svr demo_clnt
  1004. X
  1005. Xdemo_svr: $(SOBJS)
  1006. X    $(CC) $(CFLAGS) -o $@ $(SOBJS) $(RPCLIB)
  1007. X
  1008. Xdemo_clnt: $(COBJS)
  1009. X    $(CC) $(CFLAGS) -o $@ $(COBJS) $(RPCLIB)
  1010. X
  1011. Xdemo.c: demo_xdr.x demo_xdr.h
  1012. X    $(RPCGEN) -s $(PROTO) demo_xdr.x -o $@
  1013. X
  1014. Xdemo_xdr.c: demo_xdr.x
  1015. Xdemo_xdr.o: demo_xdr.c demo_xdr.h
  1016. Xdemo_proc.o: demo_xdr.h
  1017. Xdemo_clnt.o: demo_xdr.h
  1018. X
  1019. Xclean:
  1020. X    -rm -f *.o *.h demo_clnt demo_svr demo_xdr.c demo.c
  1021. SHAR_EOF
  1022. if test 1274 -ne "`wc -c < 'rpc/rpcgen/test/Makefile'`"
  1023. then
  1024.     echo shar: "error transmitting 'rpc/rpcgen/test/Makefile'" '(should have been 1274 characters)'
  1025. fi
  1026. chmod 664 'rpc/rpcgen/test/Makefile'
  1027. fi
  1028. echo shar: "extracting 'rpc/rpcgen/test/demo_clnt.c'" '(3254 characters)'
  1029. if test -f 'rpc/rpcgen/test/demo_clnt.c'
  1030. then
  1031.     echo shar: "will not over-write existing file 'rpc/rpcgen/test/demo_clnt.c'"
  1032. else
  1033. sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/test/demo_clnt.c'
  1034. X/*
  1035. X *  Client program for rpcgen demo
  1036. X */
  1037. X
  1038. X#include <stdio.h>
  1039. X#include <rpc/rpc.h>
  1040. X#include "demo_xdr.h"
  1041. X
  1042. Xchar *Prog, *Host;
  1043. X
  1044. Xstruct Calls {
  1045. X    char    *name;            /* name of call */
  1046. X    enum ret_status arg_type;    /* arg type expected */
  1047. X    int    procno;            /* proc number */
  1048. X} Calls[] = {
  1049. X    { "ctime",    RET_CLOCK,    CTIME        },
  1050. X    { "localtime",    RET_CLOCK,    LOCALTIME    },
  1051. X    { "gmtime",    RET_CLOCK,    GMTIME        },
  1052. X    { "asctime",    RET_TM,        ASCTIME        },
  1053. X    { "timezone",    RET_TZ,        TIMEZONE    },
  1054. X    { "dysize",    RET_YEAR,    DYSIZE        },
  1055. X    { NULL }
  1056. X};
  1057. X
  1058. Xchar     *Arg;
  1059. Xdemo_res Res;
  1060. Xxdrproc_t Xargs, Xres;
  1061. X
  1062. Xmain(argc, argv)
  1063. Xchar **argv;
  1064. X{
  1065. X    struct Calls *callp;
  1066. X    int ret;
  1067. X
  1068. X    Prog = argv[0];
  1069. X    if (argc < 3)
  1070. X        usage();
  1071. X
  1072. X    for (callp = Calls; callp->name; callp++)
  1073. X        if (!strcmp(callp->name, argv[2]))
  1074. X            break;
  1075. X    if (callp->name == NULL) {
  1076. X        fprintf(stderr, "%s: call \"%s\" not recognized.\n",
  1077. X            Prog, argv[2]);
  1078. X        exit(1);
  1079. X    }
  1080. X    Host = argv[1];
  1081. X    argc -= 3; argv += 3;
  1082. X    getargs(argc, argv, callp);
  1083. X    Xres = xdr_demo_res;
  1084. X    if (ret = callrpc(Host, DEMOPROG, DEMOVERS, callp->procno,
  1085. X        Xargs, Arg, Xres, &Res))
  1086. X    {
  1087. X        fprintf(stderr, "%s: rpc failed: ", Prog);
  1088. X        clnt_perrno(ret);
  1089. X        fprintf(stderr, "\n");
  1090. X        exit(1);
  1091. X    }
  1092. X    printres(callp);
  1093. X}
  1094. X
  1095. Xgetargs(argc, argv, callp)
  1096. Xint argc;
  1097. Xchar **argv;
  1098. Xstruct Calls *callp;
  1099. X{
  1100. X    static long l_arg;
  1101. X    static timeval tv;
  1102. X    static tzargs tz_arg;
  1103. X
  1104. X    gettimeofday(&tv, &tz_arg);
  1105. X    switch (callp->arg_type) {
  1106. X        case RET_CLOCK:
  1107. X        l_arg = (long)(argc > 0? atoi(argv[0]) : tv.tv_sec);
  1108. X        Arg = (char *)&l_arg;
  1109. X        Xargs = xdr_clock;
  1110. X        break;
  1111. X        case RET_TM:
  1112. X        l_arg = (long)(argc > 0? atoi(argv[0]) : tv.tv_sec);
  1113. X        Arg = (char *)localtime(&l_arg);
  1114. X        Xargs = xdr_tm;
  1115. X        break;
  1116. X        case RET_TZ:
  1117. X        if (argc == 1) {
  1118. X            fprintf(stderr, "\
  1119. X%s: call \"%s\" takes two arguments.\n", Prog, callp->name);
  1120. X            exit(1);
  1121. X        } else if (argc > 1) {
  1122. X            tz_arg.zone = atoi(argv[0]);
  1123. X            tz_arg.dst = atoi(argv[1]);
  1124. X        }
  1125. X        Arg = (char *)&tz_arg;
  1126. X        Xargs = xdr_tzargs;
  1127. X        break;
  1128. X        case RET_YEAR:
  1129. X        l_arg = (argc > 0? atoi(argv[0]) : 1986);
  1130. X        Arg = (char *)&l_arg;
  1131. X        Xargs = xdr_int;
  1132. X        break;
  1133. X        default:
  1134. X        fprintf(stderr, "%s: panic: unknown arg type %d\n",
  1135. X            Prog, callp->arg_type);
  1136. X        exit(1);
  1137. X    }
  1138. X}
  1139. X
  1140. Xprintres(callp)
  1141. Xstruct Calls *callp;
  1142. X{
  1143. X    switch (Res.which) {
  1144. X        case RET_DATE:
  1145. X        printf("date from %s: %s\n", Host, Res.demo_res.date);
  1146. X        break;
  1147. X        case RET_TM:
  1148. X#define TZP(x) Res.demo_res.tmp->tm_/**/x
  1149. X        printf("\
  1150. Xtime info from %s: sec=%d, min=%d, hour=%d, mday=%d, mon=%d,\n\
  1151. X                   year=%d, wday=%d, yday=%d, isdst=%d\n",
  1152. X            Host, TZP(sec), TZP(min), TZP(hour), TZP(mday),
  1153. X            TZP(mon), TZP(year), TZP(wday), TZP(yday), TZP(isdst));
  1154. X        break;
  1155. X        case RET_STR:
  1156. X        printf("Return string from %s: %s\n", Host, Res.demo_res.str);
  1157. X        break;
  1158. X        case RET_DAYS:
  1159. X        printf("Return from %s: %d days\n", Host, Res.demo_res.days);
  1160. X        break;
  1161. X        case RET_ERROR:
  1162. X        printf("%s returned error %d (%s)\n", Host,
  1163. X            Res.demo_res.err.err_number,
  1164. X            Res.demo_res.err.err_text);
  1165. X        break;
  1166. X        default:
  1167. X        printf("%s returned an unknown return type (%d)\n",
  1168. X            Host, Res.which);
  1169. X        break;
  1170. X    }
  1171. X}
  1172. X
  1173. Xusage()
  1174. X{
  1175. X    struct Calls *callp;
  1176. X
  1177. X    fprintf(stderr, "usage: %s host call [args]\n", Prog);
  1178. X    fprintf(stderr, "valid calls are:\n");
  1179. X    for (callp = Calls; callp->name; callp++)
  1180. X        fprintf(stderr, "\t%s\n", callp->name);
  1181. X    exit(1);
  1182. X}
  1183. SHAR_EOF
  1184. if test 3254 -ne "`wc -c < 'rpc/rpcgen/test/demo_clnt.c'`"
  1185. then
  1186.     echo shar: "error transmitting 'rpc/rpcgen/test/demo_clnt.c'" '(should have been 3254 characters)'
  1187. fi
  1188. chmod 664 'rpc/rpcgen/test/demo_clnt.c'
  1189. fi
  1190. echo shar: "extracting 'rpc/rpcgen/test/demo_proc.c'" '(833 characters)'
  1191. if test -f 'rpc/rpcgen/test/demo_proc.c'
  1192. then
  1193.     echo shar: "will not over-write existing file 'rpc/rpcgen/test/demo_proc.c'"
  1194. else
  1195. sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/test/demo_proc.c'
  1196. X/*
  1197. X *  Demo procedures
  1198. X */
  1199. X
  1200. X#include <stdio.h>
  1201. X#include <rpc/rpc.h>
  1202. X#include "demo_xdr.h"
  1203. Xstatic demo_res res;
  1204. X
  1205. Xdemo_res *
  1206. Xctime_5(arg)
  1207. Xclock *arg;
  1208. X{
  1209. X    res.which = RET_DATE;
  1210. X    res.demo_res.date = (date)ctime(arg);
  1211. X    return &res;
  1212. X}
  1213. X
  1214. Xdemo_res *
  1215. Xlocaltime_5(arg)
  1216. Xclock *arg;
  1217. X{
  1218. X    res.which = RET_TM;
  1219. X    res.demo_res.tmp = (tm *)localtime(arg);
  1220. X    return &res;
  1221. X}
  1222. X
  1223. Xdemo_res *
  1224. Xgmtime_5(arg)
  1225. Xclock *arg;
  1226. X{
  1227. X    res.which = RET_TM;
  1228. X    res.demo_res.tmp = (tm *)gmtime(arg);
  1229. X    return &res;
  1230. X}
  1231. X
  1232. Xdemo_res *
  1233. Xasctime_5(arg)
  1234. Xtm *arg;
  1235. X{
  1236. X    res.which = RET_DATE;
  1237. X    res.demo_res.date = (date)asctime(arg);
  1238. X    return &res;
  1239. X}
  1240. X
  1241. Xdemo_res *
  1242. Xtimezone_5(arg)
  1243. Xtzargs *arg;
  1244. X{
  1245. X    res.which = RET_STR;
  1246. X    res.demo_res.str = (str)timezone(arg->zone, arg->dst);
  1247. X    return &res;
  1248. X}
  1249. X
  1250. Xdemo_res *
  1251. Xdysize_5(val)
  1252. Xint *val;
  1253. X{
  1254. X    res.which = RET_DAYS;
  1255. X    res.demo_res.days = dysize(*val);
  1256. X    return &res;
  1257. X}
  1258. SHAR_EOF
  1259. if test 833 -ne "`wc -c < 'rpc/rpcgen/test/demo_proc.c'`"
  1260. then
  1261.     echo shar: "error transmitting 'rpc/rpcgen/test/demo_proc.c'" '(should have been 833 characters)'
  1262. fi
  1263. chmod 664 'rpc/rpcgen/test/demo_proc.c'
  1264. fi
  1265. echo shar: "extracting 'rpc/rpcgen/test/demo_xdr.x'" '(1834 characters)'
  1266. if test -f 'rpc/rpcgen/test/demo_xdr.x'
  1267. then
  1268.     echo shar: "will not over-write existing file 'rpc/rpcgen/test/demo_xdr.x'"
  1269. else
  1270. sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/test/demo_xdr.x'
  1271. X/*
  1272. X *  This file defines the protocol to support a demo rpc
  1273. X *  service and is designed to be processed by the `rpcgen'
  1274. X *  protocol compiler.  The Sun ctime(3) routines are used
  1275. X *  as examples.  See the rpcgen manual page for more detailed
  1276. X *  information.
  1277. X */
  1278. X
  1279. X#ifdef REL3_0
  1280. X#ifndef NULL
  1281. X#       define NULL 0
  1282. X#endif
  1283. X#endif
  1284. X
  1285. X
  1286. X/*
  1287. X *  argument / result data types
  1288. X */
  1289. X
  1290. X#define DATELEN 26
  1291. Xtypedef string date[DATELEN];
  1292. X
  1293. X#define STRLEN 80
  1294. Xtypedef string str[STRLEN];
  1295. X
  1296. Xtypedef long clock;
  1297. X
  1298. Xstruct tm {
  1299. X    int tm_sec;
  1300. X    int tm_min;
  1301. X    int tm_hour;
  1302. X    int tm_mday;
  1303. X    int tm_mon;
  1304. X    int tm_year;
  1305. X    int tm_wday;
  1306. X    int tm_yday;
  1307. X    int tm_isdst;
  1308. X};
  1309. X
  1310. Xstruct timeval {
  1311. X    u_long    tv_sec;
  1312. X    long    tv_usec;
  1313. X};
  1314. X
  1315. Xstruct timez {
  1316. X    int    tz_minuteswest;
  1317. X    int    tz_dsttime;
  1318. X};
  1319. X
  1320. Xstruct tzargs {
  1321. X    int    zone;
  1322. X    int    dst;
  1323. X};
  1324. X
  1325. X
  1326. X/*
  1327. X *  There is one generic data type for the result.  This is implemented
  1328. X *  as a union switch.  The specific union element returned is specified
  1329. X *  by ret_status.
  1330. X */
  1331. X
  1332. Xenum ret_status {
  1333. X    RET_DATE, RET_TM, RET_STR, RET_DAYS, RET_CLOCK, RET_TZ, RET_YEAR,
  1334. X    RET_ERROR
  1335. X};
  1336. X
  1337. Xstruct ret_err {
  1338. X    int    err_number;
  1339. X    str    err_text;
  1340. X};
  1341. X
  1342. Xunion demo_res switch (ret_status which) {
  1343. X    case RET_DATE:
  1344. X        date    date;
  1345. X    case RET_TM:
  1346. X        tm    *tmp;
  1347. X    case RET_STR:
  1348. X        str    str;
  1349. X    case RET_DAYS:
  1350. X        int    days;
  1351. X    case RET_ERROR:
  1352. X        ret_err err;
  1353. X};
  1354. X
  1355. X
  1356. X/*
  1357. X *  This section declares the individual procedures which are supported
  1358. X *  by this protocol.  The program number and version numbers are
  1359. X *  arbitrary in this case.  Procedures correspond to the ctime(3)
  1360. X *  time routines.
  1361. X */
  1362. X
  1363. Xprogram DEMOPROG {
  1364. X    version DEMOVERS {
  1365. X    demo_res    /* date */    CTIME(clock)        = 1;
  1366. X    demo_res    /* tm   */    LOCALTIME(clock)    = 2;
  1367. X    demo_res    /* tm   */    GMTIME(clock)        = 3;
  1368. X    demo_res    /* date */    ASCTIME(tm)        = 4;
  1369. X    demo_res    /* str  */    TIMEZONE(tzargs)    = 5;
  1370. X    demo_res    /* days */    DYSIZE(int)        = 6;
  1371. X    } = 5;
  1372. X} = 123456;
  1373. SHAR_EOF
  1374. if test 1834 -ne "`wc -c < 'rpc/rpcgen/test/demo_xdr.x'`"
  1375. then
  1376.     echo shar: "error transmitting 'rpc/rpcgen/test/demo_xdr.x'" '(should have been 1834 characters)'
  1377. fi
  1378. chmod 664 'rpc/rpcgen/test/demo_xdr.x'
  1379. fi
  1380. exit 0
  1381. #    End of shell archive
  1382.  
  1383.